# -*- coding: utf-8 -*-
'''
    File    :   ${name}.py
    Author  :   tom
    Date    :   2019.12.3
    desc    :   模拟ATM系统，实现一些简单功能.
'''

import msvcrt
import os
import sys

user_list = [{'name':'张 三', 'card_num':'123456', 'password':'111111', 'balance':5000,'iphone':'13500000000'},
             {'name':'李 四', 'card_num':'234567', 'password':'222222', 'balance':5000,'iphone':'13600000000'}
            ]
chance = 3

#定义验证银行卡号与密码匹配的函数
def login_verify(user_card_num,user_password):
    for i in range(len(user_list)):
        if user_card_num == user_list[i]['card_num'] and user_password == user_list[i]['password']:
            print()
            return i

#银行ATM机模拟系统开启欢迎界面
def ATM():
    start_choice = ['登入','注册','退出']
    print('='*15,'银行ATM机模拟系统','='*15,'\n')
    print('{:^50}'.format('ATM'),'\n')
    for k,v in enumerate(start_choice):
        print('{}、{}'.format(k+1,v))
    print()
    print('='*15,'银行ATM机模拟系统','='*15,'\n')

#定义用星号隐藏密码输入的函数
def star_input():
    li = []
    while True:
        try:
            ch = msvcrt.getch()
        except:
            return input('你很可能不是在cmd命令行下运行，密码输入将不能隐藏:')

        #回车
        if ch in b'\r\n':
            break
        #退格
        elif ch == b'\x08':
            if li:
                li.pop()
                msvcrt.putch(b'\b')
                msvcrt.putch(b' ')
                msvcrt.putch(b'\b')
        #Esc
        elif ch == 'x1b':
            break
        else:
            li.append(ch)
            msvcrt.putch(b'*')
    return (b''.join(li).decode(encoding='utf-8'))

#登入成功后用户操作界面
def user_interface():
    start_choice = ['查询', '取款', '存款','转账','修改密码','退出']
    print('='*15,'登入用户操作界面','='*15,'\n')
    for k,v in enumerate(start_choice):
        print('{}、{}'.format(k+1,v))
    print()
    print('='*15,'银行ATM机模拟系统','='*15,'\n')

#用户信息查询
def inquire(user_id):
    print('='*15,'登入用户查询界面','='*15,'\n')
    print('{0:<4}|{1:<19}|{2:<6}|{3:<8}|{4:<10}\n'.format('姓 名','卡 号','密码','余额','电话'))
    print('{0:<4}|{1:<21}|{2:<8}|{3:<7}RMB|{4:<10}\n'.format(user_list[user_id]['name'],
                                                             user_list[user_id]['card_num'],
                                                             user_list[user_id]['password'],
                                                             user_list[user_id]['balance'],
                                                             user_list[user_id]['iphone']
                                                          ))

#用户取款
def withdrawal(user_id):
    global user_list
    print('=' * 15, '登入用户取款界面', '=' * 15, '\n')
    money = input('请输入取款金额:')
    if not money.isdigit():
        print('输入的不是数字')
        return
    i = user_list[user_id]['balance']-int(money)
    if i >=0:
        user_list[user_id]['balance'] -= int(money)
        print('取款成功')
    else:
        print('您的余额不足\n')


#用户存款
def deposit(user_id):
    global user_list
    print('=' * 15, '登入用户存款界面', '=' * 15, '\n')
    money = input('请输入存款金额:')
    if not money.isdigit():
        print('输入的不是数字')
        return
    user_list[user_id]['balance'] += int(money)
    print('存款成功')

#用户转账
def transfer(user_id):
    global user_list
    print('=' * 15, '登入用户转账界面', '=' * 15, '\n')
    transfer_card_id = input('请输入转账的银行卡卡号：')
    transfer_money = input('请输入转账金额：')
    if not transfer_money.isdigit():
        print('输入的不是数字')
        return
    if user_list[user_id]['balance']-int(transfer_money) < 0:
        print('您的余额不够')
        return
    else:
        for i in range(len(user_list)):
            if transfer_card_id == user_list[i]['card_num']:
                user_list[user_id]['balance'] -= int(transfer_money)
                user_list[i]['balance'] += int(transfer_money)
                print('转账成功')
                return
        else:
            print('找不到您输入的银行卡卡号')
            return

#用户更改密码
def change_password(user_id):
    global user_list
    print('=' * 15, '登入用户更改密码界面', '=' * 15, '\n')
    old_password = input('请输入旧密码：')
    new_password1 = input('请输入6位纯数字新密码：')
    new_password2 = input('请再次输入6位纯数字新密码：')

    if old_password == user_list[user_id]['password']:
        if not new_password1.isdigit():
            print('密码只能是6位纯数字，修改密码失败\n')
            return
        elif new_password1.isdigit():
            if len(new_password1) != 6:
                print('密码只能是6位纯数字，修改密码失败\n')
                return
            elif len(new_password1) == 6 and new_password1 == new_password2:
                    user_list[user_id]['password'] = new_password1
                    print('更改密码成功')
            else:
                print('修改密码失败，您2次输入的新密码不一致\n')
    else:
        print('旧密码输入错误')

#注册新用户
def new_login():
    global user_list
    new_user = {}
    print('=' * 15, '用户注册界面', '=' * 15, '\n')
    new_name = input('请输入姓名：')
    new_card = input('请输入纯数字卡号：')
    new_password1 = input('请输入6位纯数字密码：')
    new_password2 = input('请再次输入密码：')
    new_iphone = input('请输入电话号码：')
    for i in range(len(user_list)):
        if new_card == user_list[i]['card_num']:
            print('您输入的卡号已存在，注册未成功\n')
            return

    if not new_card.isdigit():
        print('您输入的不是纯数字卡号，注册未成功\n')
        return

    elif  new_password1.isdigit():
        if len(new_password1) !=6:
            print('密码只能是6位纯数字，注册未成功\n')
            return
        elif new_password1 != new_password2:
            print('您2次输入的新密码不一致，注册未成功\n')
            return
    elif not new_password1.isdigit():
        print('密码只能是6位纯数字，注册未成功\n')
        return

    elif not new_iphone.isdigit():
        print('电话号码只能是纯数字，注册未成功\n')
        return


    new_user['name'] = new_name
    new_user['card_num'] = new_card
    new_user['password'] = new_password1
    new_user['balance'] = 5000
    new_user['iphone'] = new_iphone

    user_list.append(new_user)
    print('注册成功')

def interface_choice():
    global user_list
    global chance
    while True:
        user_card_num = input('请输入您的银行卡卡号：')
        print('请输入您的银行卡密码：', end='', flush=True)
        user_password = star_input()
        user_id = login_verify(user_card_num, user_password)
        if user_id != None:
            print('登入成功')
            while True:
                user_interface()
                key_word = input('请根据编号选择您所需要的服务:')
                print()
                if key_word == '1':
                    inquire(user_id)
                    input('按任意键返回上一级目录:')
                    print('')
                elif key_word == '2':
                    withdrawal(user_id)
                    input('按任意键返回上一级目录:')
                    print('')
                elif key_word == '3':
                    deposit(user_id)
                    input('按任意键返回上一级目录:')
                    print('')
                elif key_word == '4':
                    transfer(user_id)
                    input('按任意键返回上一级目录:')
                    print('')
                elif key_word == '5':
                    change_password(user_id)
                    input('按任意键返回上一级目录:')
                    print('')
                elif key_word == '6':
                    return main
        else:
            if chance > 1:
                print()
                print('{}{}{}'.format('卡号或者密码输入错误，您还有', chance - 1, '次机会，请重新输入'))
                chance -= 1
            else:
                print()
                print("对不起，您输入用户名或密码错误已达3次\n")
                return main  # 这里return出来的时候最好是个函数名字，也就是不要加括号，交给接收方是调用它，避免重复调用
    return main # 这里return出来的时候最好是个函数名字，也就是不要加括号，交给接收方是调用它，避免重复调用

def main():
    ATM()
    while True:
        start_nums = input('请根据编号选择您所需要的服务:')
        if start_nums== '1' :
           interface_choice()
        elif start_nums== '2' :
            new_login()
            return main() # 这里return出来的时候最好是个函数名字，也就是不要加括号，交给接收方是调用它
        elif start_nums== '3' :
            return
        else:
            print('您输入的编号不正确，请重新输入')

if __name__ == '__main__':
    main()

    # 写的很好，就是有些return格式要稍微注意下，正常情况下，return的时候，只return 函数名回去的，避免重复调用